/* / Copyright (C) 2009 Risto Känsäkoski- Sesca ISW Ltd / / This file is part of SIP-Applet (www.sesca.com, www.purplescout.com) / / This program is free software; you can redistribute it and/or / modify it under the terms of the GNU General Public License / as published by the Free Software Foundation; either version 2 / of the License, or (at your option) any later version. / / This program is distributed in the hope that it will be useful, / but WITHOUT ANY WARRANTY; without even the implied warranty of / MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the / GNU General Public License for more details. / / You should have received a copy of the GNU General Public License / along with this program; if not, write to the Free Software / Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package com.sesca.audio; import java.util.Random; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.TargetDataLine; import javax.sound.sampled.AudioFormat.Encoding; import com.sesca.misc.Logger; import com.sun.org.apache.bcel.internal.generic.FREM; public class AdaptiveSpeakerOutput implements AudioDestination { SourceDataLine line; double f1 = 1209; double f2 = 697; int index = 0; int buffering = 10; int frameLengthMillis = 20; long receivedFrames = 0; long timePlayed = 0; long startTime = 0; long t1 = 0; long t2 = 0; boolean initialFill = true; // AudioOutputStream stream; private void init(AudioFormat format) { DataLine.Info lineInfo = new DataLine.Info(SourceDataLine.class, format); // tähän // voi // lisätä // buffer // sizen if(!AudioSystem.isLineSupported(lineInfo)) { System.err.println("ERROR: AudioLine not supported by this System."); } try { line = (SourceDataLine) AudioSystem.getLine(lineInfo); // if (DEBUG) println("SourceDataLine: "+source_line); line.open(format); // tähän voi lisätä buffer sizen Logger.debug("Line opened"); } catch (LineUnavailableException e) { System.err.println("ERROR: LineUnavailableException at AudioReceiver()"); e.printStackTrace(); } if(!line.isOpen()) { Logger.error("Linja on kiinni"); } /* else { line.start(); Logger.debug("Line started"); } */ } public void init() { AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000, 16, 1, 2, 8000, false); init(format); } public void close() { //line.flush(); line.drain(); line.close(); long t = System.currentTimeMillis()-startTime; // System.out.println("Play time="+t+" ms. Data time="+receivedFrames*frameLengthMillis+" ms. Delta="+((receivedFrames*frameLengthMillis)-t)+" ms."+" Line buffer available="+line.available()); System.out.println("Speaker output stopped."); } public void init(AudioDestinationListener listener, AudioFormat format, int frameSize) { init(); } public void go() {} public void onReceivedDestinationFrame(byte[] b) { receivedFrames++; t2=System.currentTimeMillis(); long t = t2-startTime; long latency = t2-t1; t1=t2; if (receivedFrames*frameLengthMillis % 1000 == 0) { // System.out.println("Play time="+t+" ms. Data time="+receivedFrames*frameLengthMillis+" ms. Delta="+((receivedFrames*frameLengthMillis)-t)+" ms."+" Line buffer available="+line.available()+" Latency="+latency+" ms."); } if(line == null) Logger.error("Line=null"); int a = line.available(); int s = line.getBufferSize(); //System.out.println(a+"/"+s+" available"); //if (s-a<(b.length) && buffering == -1) if (s-a==0 && buffering == -1) { line.stop(); buffering = 5; // System.out.println("Buffer is empy!"); } //System.out.println(s-a+" bytes data in buffer ("+b.length+")"); line.write(b, 0, b.length); if (buffering==0) { line.start(); buffering--; //System.out.println("Buffer filled. Starting output."); if (initialFill) { initialFill=false; startTime=System.currentTimeMillis(); } } if (buffering>=0) { buffering--; //System.out.println("Filling buffer"); } } public void stop() { if(line.isOpen()) { line.drain(); line.stop(); } else { System.err.print("WARNING: Audio stop error: source line is not open."); } // source_line.close(); } public void play() { if(line.isOpen()) line.start(); else { System.err.print("WARNING: Audio play error: source line is not open."); } } }